# 创建函数:
# def 函数名（[形参1，形参2]）：
#      代码块
def fn():
    print(1)


fn()


# 定义函数一般是实现某个功能的
# 定义函数，求两个数和
def fn1(a=2, b=4):
    print("sum = ", a + b)


fn1(1, 2)

# 定义一个函数
# 定义形参时，可以为形参指定默认值
# 指定了默认值以后。如果用户传递了参数则默认值没有任何作用
# 如果用户没有传递，则默认值会生效
fn1(1)  # 1,4


# 实参的传递方式
# 位置参数：对对应位置的实参赋值给对应位置的形参
fn1(1, 2)
# 关键字参数
# 关键字参数可以不按照形参定义的传递，而直接更具参数名去传递
fn1(b=1, a=2)

# 关键字参数和位置参数可以混合使用，但不能把关键字放在前面使用，要在位置参数的后面使用
# fn(1, b=2)


# 实参可以传递任意类型的对象


# 命名空间（namespace)
# 命名空间就是变量存储的位置，每个变量都需要指定的命名空间中


# 递归
def fn5(num):
    if num == 1:
        return 1
    return num * fn5(num - 1)


n = fn5(4)
print(n)


def power(n, i):
    if i == 1:
        return n
    return n * power(n, i - 1)


n = power(3, 2)
print(n)


# 高阶函数，可以传递函数作为参数
# 当外面使用一个函数作为参数，函数保存的·代码·传递给函数中


# fillter()
# fillter()可以从序列中过滤出符合条件的元素，保存到一个新序列中
# 参数：
# 1.函数，根据该函数来过滤的序列（可迭代的结构）
# 2.需要过滤的序列（可迭代的结构）
# 返回值：
# 过滤后的新序列（可迭代的结构）

# filter(fn4,l)#其返回的是一个object的对象
# 如果想要看见里面具体的内容，用list转一下
# fn4做为参数传递进filter（）中，fn4不要加括号，fn4直接是作为一个参数
# filter()调用完毕以后，fn4就已经没用


# 匿名函数 lambda()函数表达式
# lambda函数表达式是专门用来创建简单的函数，他是函数创建的又一种方式
# 语法：lambda 参数列表：返回值
def fn5(a, b):
    return a + b


fn6 = lambda a, b: a + b
print(fn6(10, 20))
l = {1, 2, 3, 4, 5}
lambda i: i % 3 == 0
r = filter(lambda i: i % 3 == 0, l)
print(list(r))


# map()函数可以对可跌倒对象中的所有元素做指定的操作，然后将其添加到一个新的对象
# 返回
l = [1, 2, 3, 4, 5, 6]
r = map(lambda i: i**2, l)
print(list(r))


# sort()
# 该方法用来对列表中的元素进行排序
# sort()方法默认可以直接比较列表的元素大小
# 在sort()可以接收一个关键字参数，key
# key需要一个函数作为参数，当设置了函数作为参数
# 每次都会以列表中的一个元素作为参数来调用函数，并且使用函数的返回值来比较元素大小
l = [2, 5, "1", 3, "6", "4"]
l.sort(key=int)


# sorted()
# 这个函数和sort()的用法一致，但是sorted()可以对
# 任意的序列进行排序，并且使用sorted()排序不会影响原来的对象
# 而是返回一个新对象
l = "122111212131"
print(sorted(l, key=int))
